package com.buanalintas.sandals.pos.returshop;

import com.buanalintas.bynga.Access;
import com.buanalintas.bynga.Action;
import com.buanalintas.bynga.Controller;
import com.buanalintas.bynga.Dictionary;
import com.buanalintas.bynga.Field;
import com.buanalintas.bynga.Logger;
import com.buanalintas.bynga.Page;
import com.buanalintas.bynga.Persistence;
import com.buanalintas.bynga.Sequence;
import com.buanalintas.bynga.Template;
import com.buanalintas.bynga.Utility;
import com.buanalintas.bynga.entities.MasterUnit;
import com.buanalintas.bynga.formatter.DateFormatter;
import com.buanalintas.sandals.pos.entities.PosMasterItemStock;
import com.buanalintas.sandals.pos.entities.PosMasterStatus;
import com.buanalintas.sandals.pos.entities.PosTransactionItemStock;
import com.buanalintas.sandals.pos.entities.PosTransactionReturShop;
import com.buanalintas.sandals.pos.entities.PosTransactionReturShopDetail;
import com.buanalintas.sandals.pos.item.Item;
import com.buanalintas.sandals.pos.returshopdetail.ReturShopDetail;
import com.buanalintas.sandals.pos.status.Status;
import java.util.Calendar;
import java.util.List;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ReturShop extends Page {

    private Field returShopId;
    private Field returShopUserId;
    private Field returShopUnitId;
    private Field returShopDate;
    private Field returShopNumber;
    private Field returShopProgress;
    private Field returShopRejectReason;
    private Field returShopDescription;
    private Field returShopTimestamp;
    private Action actionRevision = new Action("revisi", "Revision Request");
    private Action actionReject = new Action("reject", "Reject Request");
    private Action actionAgree = new Action("approve", "Agree Request");

    public ReturShop() {
        super();
        setTheClass(PosTransactionReturShop.class);
        setPageDetail(ReturShopDetail.class);

        returShopId = new Field();
        returShopId.setName("returShopId");
        returShopId.setCaption("id");
        returShopId.setListProperties("");
        returShopId.setInputProperties("");
        getFields().add(returShopId);

        returShopUserId = new Field();
        returShopUserId.setName("returShopUserId");
        returShopUserId.setCaption("user");
        returShopUserId.setListProperties("");
        returShopUserId.setInputProperties("");
        getFields().add(returShopUserId);

        returShopUnitId = new Field();
        returShopUnitId.setName("returShopUnitId");
        returShopUnitId.setCaption("unit");
        returShopUnitId.setListProperties("");
        returShopUnitId.setInputProperties("");
        getFields().add(returShopUnitId);

        returShopDate = new Field();
        returShopDate.setName("returShopDate");
        returShopDate.setCaption("date");
        returShopDate.setListProperties(" align=\"center\" width=\"10%\" nowrap");
        returShopDate.setInputProperties(" size=\"8\"");
        returShopDate.setRequired(true);
        returShopDate.setDefaultValue(Utility.getTimestamp());
        getFields().add(returShopDate);

        returShopNumber = new Field();
        returShopNumber.setName("returShopNumber");
        returShopNumber.setCaption("number");
        returShopNumber.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        returShopNumber.setInputProperties(" size=\"20\" readonly");
        returShopNumber.setRequired(true);
        getFields().add(returShopNumber);
        
        returShopProgress = new Field();
        returShopProgress.setName("returShopProgress");
        returShopProgress.setCaption("progress");
        returShopProgress.setListProperties(" width=\"10%\" nowrap");
        returShopProgress.setInputProperties("");
        returShopProgress.setInputType(Field.INPUT_COMBO_BOX);
        returShopProgress.getOptions().add(new String[]{"1", "New"});
        returShopProgress.getOptions().add(new String[]{"2", "Revision"});
        returShopProgress.getOptions().add(new String[]{"3", "Rejected"});
        returShopProgress.getOptions().add(new String[]{"4", "Approved"});
        getFields().add(returShopProgress);

        returShopRejectReason = new Field();
        returShopRejectReason.setName("returShopRejectReason");
        returShopRejectReason.setCaption("reason");
        returShopRejectReason.setListProperties(" width=\"10%\" nowrap");
        returShopRejectReason.setInputProperties("");
        returShopRejectReason.setInputCase(Field.CASE_UPPER);
        getFields().add(returShopRejectReason);

        returShopDescription = new Field();
        returShopDescription.setName("returShopDescription");
        returShopDescription.setCaption("description");
        returShopDescription.setListProperties(" align=\"left\" width=\"55%\" nowrap");
        returShopDescription.setInputProperties(" cols=\"50\" rows=\"5\"");
        returShopDescription.setInputType(Field.INPUT_TEXT_AREA);
        returShopDescription.setInputCase(Field.CASE_UPPER);
        getFields().add(returShopDescription);

        returShopTimestamp = new Field();
        returShopTimestamp.setName("returShopTimestamp");
        returShopTimestamp.setCaption("timestamp");
        returShopTimestamp.setListProperties(" align=\"center\" width=\"10%\" nowrap");
        returShopTimestamp.setInputProperties(" size=\"12\"");
        getFields().add(returShopTimestamp);

        getActions().add(Action.TRANS_ADD);
        getActions().add(Action.TRANS_EDIT);
        getActions().add(Action.TRANS_VIEW);
        
        fillFields();

        getFieldsAdd().clear();
        getFieldsAdd().add(returShopNumber);
        getFieldsAdd().add(returShopDate);
        getFieldsAdd().add(returShopDescription);

        getFieldsEdit().clear();
        getFieldsEdit().add(returShopNumber);
        getFieldsEdit().add(returShopDate);
        getFieldsEdit().add(returShopDescription);

        getFieldsList().clear();
        getFieldsList().add(returShopNumber);
        getFieldsList().add(returShopDate);
        getFieldsList().add(returShopRejectReason);
        getFieldsList().add(returShopDescription);
        getFieldsList().add(returShopProgress);

        getFieldsView().clear();
        getFieldsView().add(returShopDate);
        getFieldsView().add(returShopNumber);
        getFieldsView().add(returShopDescription);
        getFieldsView().add(returShopUserId);
        getFieldsView().add(returShopUnitId);
        getFieldsView().add(returShopRejectReason);
        getFieldsView().add(returShopProgress);
        getFieldsView().add(returShopTimestamp);

        setController(new ReturShopController(this));
        getActions().add(actionRevision);
        getActions().add(actionAgree);
        getActions().add(actionReject);

        setExportList(getClass().getResourceAsStream("ReturList.jasper"));
        setExport(getClass().getResourceAsStream("Retur.jasper"));
    }

    @Override
    public void afterInit(HttpServletRequest req, HttpServletResponse res) {
        returShopDate.setFormater(DateFormatter.getInstanceDate(this));
        returShopTimestamp.setFormater(DateFormatter.getInstanceDateTime(this));
    }

    @Override
    public void beforeAdd() {
        returShopNumber.setDefaultValue(generate());
    }

    @Override
    public void beforeList() {
        if (!getCurrentUnit().getUnitId().equals(1)) {
            getController().setCondition("t.returShopUnitId.unitId=" + getCurrentUnit().getUnitId());
        }
    }

    @Override
    public String addJavascript() {
        return "<script>function __revision(id) {var reason = prompt('" + Dictionary.getValue(this, "Enter revision reason") + "?', ''); if (reason != null) { location.href = \"?m=" + getMenu().getMenuName() + "&a=" + actionRevision.getName() + "&id=\"+id+\"&reason=\"+escape(reason); } return false; };function __reject(id) {var reason = prompt('" + Dictionary.getValue(this, "Enter rejected reason") + "?', ''); if (reason != null) { location.href = \"?m=" + getMenu().getMenuName() + "&a=" + actionReject.getName() + "&id=\"+id+\"&reason=\"+escape(reason); } return false; }</script>";
    }

    @Override
    public boolean isGranted(Action action, Object data) {
        boolean granted = super.isGranted(action, data);
        if (granted) {
            PosTransactionReturShop returShop = (PosTransactionReturShop) data;
            if (action.equals(Action.EDIT) || action.equals(Action.TRANS_EDIT) || action.equals(Action.DELETE)) {
                granted = returShop.getReturShopProgress() == null || returShop.getReturShopProgress().equals("1") || returShop.getReturShopProgress().equals("2");
            }
        }
        return granted;
    }

    @Override
    public String delete(Object data) {
        String delete = super.delete(data);
        if (delete == null) {
            PosTransactionReturShop returShop = (PosTransactionReturShop) data;
            if (!"1".equals(returShop.getReturShopProgress())) {
                delete = Dictionary.getValue(this, "can not be deleted");
            }
        }
        return delete;
    }

    @Override
    public StringBuffer processCustomRowCommand(StringBuffer template, Page page, Object data) {
        StringBuffer commands = new StringBuffer();
        StringBuffer command = null;
        PosTransactionReturShop returShop = (PosTransactionReturShop) data;
        if (returShop.getReturShopProgress() == null || returShop.getReturShopProgress().equals("1")) {
            if (Access.isGranted(page, actionRevision)) {
                command = new StringBuffer(template.toString());
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_LINK, "?m=" + page.getMenu().getMenuName() + "&a=" + actionRevision.getName() + "&id=" + Utility.encode(Utility.getStringValue(data, page.getPrimaryKeyField())));
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_TITLE, Dictionary.getValue(page, "Revision request"));
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_PROPERTIES, " onclick=\"return __revision('" + Utility.encode(Utility.getStringValue(data, page.getPrimaryKeyField())) + "')\"");
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_IMAGE, "?image=command-revision.png");
                commands.append(command.toString());
            }
            if (Access.isGranted(page, actionReject)) {
                command = new StringBuffer(template.toString());
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_LINK, "?m=" + page.getMenu().getMenuName() + "&a=" + actionReject.getName() + "&id=" + Utility.encode(Utility.getStringValue(data, page.getPrimaryKeyField())));
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_TITLE, Dictionary.getValue(page, "Reject request"));
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_PROPERTIES, " onclick=\"return __reject('" + Utility.encode(Utility.getStringValue(data, page.getPrimaryKeyField())) + "')\"");
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_IMAGE, "?image=command-reject.png");
                commands.append(command.toString());
            }
            if (Access.isGranted(page, actionAgree)) {
                command = new StringBuffer(template.toString());
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_LINK, "?m=" + page.getMenu().getMenuName() + "&a=" + actionAgree.getName() + "&id=" + Utility.encode(Utility.getStringValue(data, page.getPrimaryKeyField())));
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_TITLE, Dictionary.getValue(page, "Approve request"));
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_PROPERTIES, " onclick=\"return confirm('" + Dictionary.getValue(page, "Approve request") + "?')\"");
                Utility.replaceAll(command, Template.TABLE_ROW_MENU_COMMAND_CUSTOM_IMAGE, "?image=command-approve.png");
                commands.append(command.toString());
            }
        }
        return commands;
    }

    @Override
    public String doAction() {

        String id = Utility.decode(Utility.getParameter(getRequest(), "id"));
        if (id != null && !id.trim().equals("")) {
            PosTransactionReturShop data = (PosTransactionReturShop) getController().getData(id);
            if (getAction().equals(actionRevision)) {
                String reason = Utility.getParameter(getRequest(), "reason");
                if (reason == null || reason.trim().equals("")) {
                    return "err:" + Dictionary.getValue(this, "Please enter revision reason");
                }
                try {
                    data.setReturShopProgress("2");
                    data.setReturShopRejectReason(Utility.getParameter(getRequest(), "reason"));
                    getController().update(data);
                    return "ok:" + Dictionary.getValue(this, "Data with") + " " + getObjectInfo(data) + " " + Dictionary.getValue(this, "rejected succesfully");
                } catch (Exception e) {
                    Logger.getInstance().log(e);
                    return "err:" + Dictionary.getValue(this, "Data with") + " " + getObjectInfo(data) + " " + Dictionary.getValue(this, "rejected failed") + ": " + e.getMessage();
                }
            } else if (getAction().equals(actionReject)) {
                String reason = Utility.getParameter(getRequest(), "reason");
                if (reason == null || reason.trim().equals("")) {
                    return "err:" + Dictionary.getValue(this, "Please enter rejected reason");
                }
                try {
                    data.setReturShopProgress("3");
                    data.setReturShopRejectReason(Utility.getParameter(getRequest(), "reason"));
                    getController().update(data);
                    return "ok:" + Dictionary.getValue(this, "Data with") + " " + getObjectInfo(data) + " " + Dictionary.getValue(this, "rejected succesfully");
                } catch (Exception e) {
                    Logger.getInstance().log(e);
                    return "err:" + Dictionary.getValue(this, "Data with") + " " + getObjectInfo(data) + " " + Dictionary.getValue(this, "rejected failed") + ": " + e.getMessage();
                }
            } else if (getAction().equals(actionAgree)) {
                EntityManager em = getEntityManager();
                PosMasterStatus statusGood = Status.getStatusGood(em);
                try {
                    em.getTransaction().begin();
                    PosTransactionReturShop returShop = (PosTransactionReturShop) data;
                    List<PosTransactionReturShopDetail> details = em.createQuery("SELECT t FROM PosTransactionReturShopDetail t WHERE t.returShopDetailReturShopId.returShopId='" + id + "'").setHint(Persistence.REFRESH_HINT, true).getResultList();
                    MasterUnit unit = (MasterUnit) em.createQuery("SELECT t FROM MasterUnit t WHERE t.unitId='1'").setHint(Persistence.REFRESH_HINT, true).getSingleResult();
                    for (PosTransactionReturShopDetail detail : details) {
                        PosMasterItemStock stockUnit = Item.getStock(em, detail.getReturShopDetailItemId(), returShop.getReturShopUnitId(), statusGood, detail.getReturShopDetailItemId().getItemColorId(), detail.getReturShopDetailSizeId());
                        PosMasterItemStock stockInventory = Item.getStock(em, detail.getReturShopDetailItemId(), unit, statusGood, detail.getReturShopDetailItemId().getItemColorId(), detail.getReturShopDetailSizeId());
                        PosTransactionItemStock itemStock = new PosTransactionItemStock();
                        PosTransactionItemStock itemStocks = new PosTransactionItemStock();

                        Integer senderStock = stockUnit.getItemStockValue() - detail.getReturShopDetailQuantity();
                        Integer destinationStock = stockInventory.getItemStockValue() + detail.getReturShopDetailQuantity();

                        itemStock.setItemStockId(Sequence.next(itemStock));
                        itemStock.setItemStockItemId(detail.getReturShopDetailItemId());
                        itemStock.setItemStockSizeId(detail.getReturShopDetailSizeId());
                        itemStock.setItemStockColorId(detail.getReturShopDetailItemId().getItemColorId());
                        itemStock.setItemStockUnitId(stockUnit.getItemStockUnitId());
                        itemStock.setItemStockStatusId(statusGood);
                        itemStock.setItemStockType("5");
                        itemStock.setItemStockLast(stockUnit.getItemStockValue());
                        itemStock.setItemStockValue(detail.getReturShopDetailQuantity());
                        itemStock.setItemStockCurrent(stockUnit.getItemStockValue() - detail.getReturShopDetailQuantity());
                        itemStock.setItemStockUserId(returShop.getReturShopUserId());
                        itemStock.setItemStockTimestamp(Utility.getTimestamp());
                        em.persist(itemStock);

                        itemStocks.setItemStockId(Sequence.next(itemStocks));
                        itemStocks.setItemStockItemId(detail.getReturShopDetailItemId());
                        itemStocks.setItemStockSizeId(detail.getReturShopDetailSizeId());
                        itemStocks.setItemStockColorId(detail.getReturShopDetailItemId().getItemColorId());
                        itemStocks.setItemStockUnitId(unit);
                        itemStocks.setItemStockStatusId(statusGood);
                        itemStocks.setItemStockType("5");
                        itemStocks.setItemStockLast(stockInventory.getItemStockValue());
                        itemStocks.setItemStockValue(detail.getReturShopDetailQuantity());
                        itemStocks.setItemStockCurrent(stockInventory.getItemStockValue() + detail.getReturShopDetailQuantity());
                        itemStocks.setItemStockUserId(getCurrentUser());
                        itemStocks.setItemStockTimestamp(Utility.getTimestamp());
                        em.persist(itemStocks);

                        stockUnit.setItemStockValue(senderStock);
                        stockInventory.setItemStockValue(destinationStock);
                    }
                    returShop.setReturShopProgress("4");
                    em.getTransaction().commit();
                } catch (Exception e) {
                    Logger.getInstance().log(e);
                    return "err:" + Dictionary.getValue(this, "Data with") + " " + getObjectInfo(data) + " " + Dictionary.getValue(this, "approved failed") + ": " + e.getMessage();
                }
            }
        }
        return null;
    }

    class ReturShopController extends Controller {

        public ReturShopController(Page page) {
            super(page);
            setOrder(returShopTimestamp);
            setOrderType("DESC");
        }

        @Override
        public void beforeInsert(Object data, List detail) {
            PosTransactionReturShop returShop = (PosTransactionReturShop) data;
            returShop.setReturShopNumber(generate());
            returShop.setReturShopProgress("1");
            returShop.setReturShopUnitId(getCurrentUnit());
            returShop.setReturShopUserId(getCurrentUser());
            returShop.setReturShopTimestamp(Utility.getTimestamp());
            
            
//             for (int i = detail.size() - 1; i > 0; i--) {
//                PosTransactionReturShopDetail d1 = (PosTransactionReturShopDetail) detail.get(i);
//                for (int j = 0; j < i; j++) {
//                    PosTransactionReturShopDetail d2 = (PosTransactionReturShopDetail) detail.get(j);
//                    if (d2.getReturShopDetailItemId().equals(d1.getReturShopDetailItemId())) {
//                        d2.setReturShopDetailQuantity(d2.getReturShopDetailQuantity()+d1.getReturShopDetailQuantity());
//                        detail.remove(i);
//                        break;
//                    }
//                }
//            }
        }

        @Override
        public void beforeUpdate(Object data, List list, List listDelete) {
            PosTransactionReturShop returShop = (PosTransactionReturShop) data;
            returShop.setReturShopProgress("1");
            returShop.setReturShopRejectReason(Dictionary.getValue(page, "Revision") + ": " + returShop.getReturShopRejectReason());
        }
    }

    public String generate() {
        String unitCode = (getCurrentUnit()).getUnitCode();
        Calendar cal = Calendar.getInstance();
        String year = "" + cal.get(Calendar.YEAR);
        String month = Utility.intToRoman(cal.get(Calendar.MONTH) + 1);
        try {
            PosTransactionReturShop returShop = (PosTransactionReturShop) getEntityManager().createQuery("SELECT t FROM PosTransactionReturShop t WHERE t.returShopNumber LIKE '%/" + unitCode + "/RES/%/" + year + "' ORDER BY t.returShopTimestamp DESC").setHint(Persistence.REFRESH_HINT, true).setFirstResult(0).setMaxResults(1).getSingleResult();
            return Utility.lpad(Integer.parseInt(returShop.getReturShopNumber().substring(0, 4)) + 1, 4, "0") + "/" + unitCode + "/RES/" + month + "/" + year;
        } catch (Exception e) {
        }
        return "0001/" + unitCode + "/RES/" + month + "/" + year;
    }

    @Override
    public void beforeExport() {
        getExportParams().put("title", Dictionary.getValue(this, "ReturShop"));
    }

    @Override
    public void beforeExportMulti() {
        beforeExport();
    }
}
